package reflection_generics_containers.reflection;

import java.lang.reflect.Constructor;

/**
 * @author LiuYan
 * @date 2023/7/16
 * 一、普通创建对象过程：
 * 1、编译期间加载字节码文件
 * 2、查找构造函数
 * 3、通过构造函数创建对象
 * 二、反射获取对象过程：
 * 1、运行期间加载字节码文件
 * 2、创建构造函数
 * 3、通过构造函数创建对象
 */
public class CreateReflectionObject {

    public static void main(String[] args) throws Exception {
        // 获取Person字节码
        Class personClass = Class.forName("reflection_generics_containers.reflection.Person");
        // 通过Class对象，创建构造方法对象（初始化无参构造方法，public修饰的构造方法，包括父类）
        Constructor constructor1 = personClass.getConstructor();
        // 通过Class对象，创建构造方法对象（初始化全参构造方法，public修饰的构造方法，包括父类）
        Constructor constructor2 = personClass.getConstructor(String.class, Integer.class, Byte.class, Boolean.class);
        // 调用无参构造方法创建对象
        Person person1 = (Person) constructor1.newInstance();
        person1.setName("LiuYan");
        System.out.println("person1=" + person1);
        // 调用有参构造方法创建对象
        Person person2 = (Person) constructor2.newInstance("LiuYan", 10, (byte) 1, true);
        System.out.println("person2=" + person2);
        // 反射通过私有构造方法创建对象，破坏单例模式
        Class singletonPersonClass = SingletonPerson.class;
        // 反射通过私有构造⽅法创建对象，破坏单例模式（获取所有访问修饰符修饰的构造方法但不包括父类）
        Constructor constructor3 = singletonPersonClass.getDeclaredConstructor();
        // 反射机制的方法，强制进行访问
        constructor3.setAccessible(true);
        SingletonPerson singletonPerson = (SingletonPerson) constructor3.newInstance();
        SingletonPerson singletonPerson1 = SingletonPerson.getSingletonPerson();
        SingletonPerson singletonPerson2 = SingletonPerson.getSingletonPerson();
        System.out.println("singletonPerson==singletonPerson1 is " + (singletonPerson == singletonPerson1));
        System.out.println("singletonPerson==singletonPerson2 is " + (singletonPerson == singletonPerson2));
        System.out.println("singletonPerson1==singletonPerson2 is " + (singletonPerson1 == singletonPerson2));
    }
}
